/**
* ============================================
* @author:syf20020816@outlook.com
* @since:20240415
* @version:0.4.3
* @type:interface
* @description:
* # NumberInput
* A numeric input component that inherits from SCard, designed for inputting numerical values within a specified range. It allows adjustments through increment and decrement actions.
* ## Properties
* - in-out property <float> minimum: The minimum value that the input can hold, default set to 0.
* - in-out property <float> maximum: The maximum value that the input can hold, default set to 100.
* - in-out property <float> value: The current numerical value of the input, initialized at 0.
* - in-out property <bool> disabled: A boolean indicating whether the input is disabled (non-interactive), default set to false.
* - in property <float> step: The step increment or decrement applied when adjusting the value, set to 1.0.
* - in property <bool> strict: A boolean to enforce strict bounds. If true, inputs outside of the min-max range are not accepted.
* - in-out property <InputType> input-type: Defines the type of numerical input allowed (e.g., integer, decimal), set to `InputType.decimal`.
*
* ## Functions
* - public function up(): Increases the input's value by the step size unless it exceeds the maximum limit or the input is disabled.
* - public function down(): Decreases the input's value by the step size unless it is less than the minimum limit or the input is disabled.
*
* ## Callbacks
* - callback accepted(float): Triggered when a new value is input and accepted within the valid range.
* - callback changed(float): Triggered every time the value is changed through user interaction.
* - callback unexpect(float): Triggered when an input is provided that does not conform to the specified restrictions (if `strict` is true).
* ============================================
*/

import { SIcon } from "../icon/index.slint";
import {UseIcons,UseSurrealismFn,ColorLevel} from "../../use/index.slint";
import { GlobalProps,ROOT-STYLES } from "../../themes/index.slint";
import { SCard } from "../card/index.slint";
export component NumberInput inherits SCard{
    card-height: self.font-size;
    width: 160px;
    clip: true;
    font-color: UseSurrealismFn.get-color(root.theme, ColorLevel.Font);
    in-out property <float> minimum: 0;
    in-out property <float> maximum: 100;
    in-out property <float> value: 0;
    in-out property <bool> disabled : false;
    in property <float> step : 1.0;
    in property <bool> strict : false;
    in-out property <InputType> input-type : InputType.decimal;
    callback accepted(float);
    callback changed(float);
    callback unexpect(float);
    public function up() {
        if disabled{
            return;
        }else{
            if input.text.to-float() + self.step > self.maximum{
                input.text = self.maximum;
            }else{
                input.text = input.text.to-float() + self.step;
            }
            self.value = input.text.to-float();
        }
    }
    public function down() {
        if disabled{
            return;
        }else{
            if input.text.to-float() - self.step < self.minimum{
                input.text = self.minimum;
            }else{
                input.text = input.text.to-float() - self.step;
            }
            self.value = input.text.to-float();
        }
    }
    Rectangle {
        x: 2px;
        height: input.has-focus? root.height : 0px;
        width: 2px;
        background: disabled ? UseSurrealismFn.get-color(root.theme, ColorLevel.Weakest) :GlobalProps.active-color;
        animate height {
            duration: ROOT-STYLES.sur-an-duration;
            easing: ROOT-STYLES.sur-an-easing;
        }
    }
    view:= HorizontalLayout {
        padding-left: root.padding-left;
        
        Rectangle {
            input := TextInput {
                property <length> computed_x;
                property <length> padding-outer: view.padding-left + view.padding-right;
                x: min(0px, max(parent.width - self.width, self.computed_x));
                width: max(parent.width, self.preferred-width);
                height: root.font-size * 2;
                color: root.font-color;
                horizontal-alignment: left;
                vertical-alignment: center;
                font-size: root.font-size;
                font-weight: root.font-weight;
                font-italic: root.font-italic;
                font-family: root.font-family;
                read-only: root.disabled;
                single-line: true;
                input-type: root.input-type;
                wrap: no-wrap;
                text: root.value;
                accepted => {
                    root.accepted(self.text.to-float())
                }
                edited => {
                    if self.text.to-float() > root.maximum || self.text.to-float() < root.minimum{
                        return;
                    }else{
                        if (root.strict) {
                            if Math.mod(self.text.to-float(), root.step) != 0{
                                root.unexpect(self.text.to-float());
                                self.text = self.text.to-float() - Math.mod(self.text.to-float(), root.step);
                            }
                        }
                    }
                    root.value = self.text.to-float();
                    root.changed(self.text.to-float())
                }

                cursor-position-changed(cpos) => {
                  if (cpos.x + self.computed_x < self.padding-outer) {
                    self.computed_x = - cpos.x + self.padding-outer;
                  } else if (cpos.x + self.computed_x > parent.width - self.padding-outer) {
                    self.computed_x = parent.width - cpos.x - self.padding-outer;
                  }
                }
            }
        }
        VerticalLayout {
            
            up-wrap:= Rectangle {
                background: UseSurrealismFn.get-color(root.theme, ColorLevel.Deeper);
                up-icon:= SIcon {
                    theme: root.theme;
                    source: UseIcons.icons.Up;
                    colorize: self.has-hover ? GlobalProps.active-color : self.get-colorize();
                    animate colorize {
                        duration: ROOT-STYLES.sur-an-duration;
                        easing: ROOT-STYLES.sur-an-easing;
                    }
                    clicked => {
                        root.up();
                    }
                }
            }
            down-wrap:= Rectangle {
                background: UseSurrealismFn.get-color(root.theme, ColorLevel.Deeper);
                down-icon:= SIcon {
                    theme: root.theme;
                    source: UseIcons.icons.Down;
                    colorize: self.has-hover ? GlobalProps.active-color : self.get-colorize();
                    animate colorize {
                        duration: ROOT-STYLES.sur-an-duration;
                        easing: ROOT-STYLES.sur-an-easing;
                    }
                    clicked => {
                        root.down();
                    }
                }
            }
        }
    }
}
